﻿using Autofac;
using Autofac.Integration.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using System.Web.Script.Serialization;
using Willow.Authorization;
using Willow.Common;
using Willow.IService;
using Willow.IService.Auth;
using Willow.IService.Sys;
using Willow.Model;
using Willow.MVC.Search;
using Willow.WebApplication.Controllers;

namespace Willow.WebApplication
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            HibernatingRhinos.Profiler.Appender.EntityFramework.EntityFrameworkProfiler.Initialize();
            // 依赖注入
            AutofacConfig.RegisterAutofac();
            //查询条件绑定Binder
            ModelBinders.Binders.Add(typeof(QueryModel), new SearchModelBinder());
            //初始化菜单
            ModuleConfig.Init();

            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }

        protected void Session_End(object sender, EventArgs e)
        {
            var sessionID = this.Session.SessionID;
            OnlineContext.Instance.RemoveUser(sessionID);
        }

        /// <summary>
        /// 异常处理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Application_Error(object sender, EventArgs e)
        {
            var httpContext = ((MvcApplication)sender).Context;
            var currentController = " ";
            var currentAction = " ";
            var currentRouteData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(httpContext));

            if (currentRouteData != null)
            {
                if (currentRouteData.Values["controller"] != null && !String.IsNullOrEmpty(currentRouteData.Values["controller"].ToString()))
                {
                    currentController = currentRouteData.Values["controller"].ToString();
                }

                if (currentRouteData.Values["action"] != null && !String.IsNullOrEmpty(currentRouteData.Values["action"].ToString()))
                {
                    currentAction = currentRouteData.Values["action"].ToString();
                }
            }

            var ex = Server.GetLastError();
            //添加异常日志
            AddErrorLog(httpContext.Request.Url.AbsolutePath, ex);

            httpContext.ClearError();
            httpContext.Response.Clear();
            httpContext.Response.StatusCode = ex is HttpException ? ((HttpException)ex).GetHttpCode() : 500;
            httpContext.Response.TrySkipIisCustomErrors = true;

            if (httpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
            {
                //如果是Ajax请求，返回json数据
                httpContext.Response.ContentType = "application/json";
                JavaScriptSerializer serializer = new JavaScriptSerializer();
                httpContext.Response.Write(ex.Message);
            }
            else
            {
                //跳转到异常视图
                var controller = new ErrorController();
                var routeData = new RouteData();
                var action = "Index";

                if (ex is HttpException)
                {
                    var httpEx = ex as HttpException;
                    switch (httpEx.GetHttpCode())
                    {
                        case 404:
                            //action = "NotFound";
                            break;
                    }
                }

                routeData.Values["controller"] = "Error";
                routeData.Values["action"] = action;
                controller.ViewData.Model = new HandleErrorInfo(ex, currentController, currentAction);
                ((IController)controller).Execute(new RequestContext(new HttpContextWrapper(httpContext), routeData));
            }
        }

        /// <summary>
        /// 添加异常日志到数据库中
        /// </summary>
        /// <param name="url">The URL.</param>
        /// <param name="ex">The ex.</param>
        private void AddErrorLog(string url, Exception ex)
        {
            var currUser = OnlineContext.Instance.GetCurrentUser();
            var log = new Sys_ErrorLog()
            {
                Id = Guid.NewGuid(),
                Ip = NetHelper.GetRequestIP(),
                URL = url,
                Message = ex.Message,
                InnerException = ex.InnerException == null ? "" : ex.InnerException.ToString(),
                StackTrace = ex.StackTrace,
                OperateDateTime = DateTime.Now
            };
            var serivce = DependencyResolver.Current.GetService<IErrorLogService>();
            serivce.Create(log);
        }

    }
}
